package com.taomus.mytools.simplec.syntax;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

import com.taomus.mytools.simplec.common.Label;
import com.taomus.mytools.simplec.common.SyntaxTuple;
import com.taomus.mytools.simplec.common.SyntaxTupleList;
import com.taomus.mytools.simplec.common.TempToken;
import com.taomus.mytools.simplec.common.Token;
import com.taomus.mytools.simplec.common.Word;
import com.taomus.mytools.simplec.common.WordEnum;
import com.taomus.mytools.simplec.utils.ErrorUtils;

public class If implements IAnalyse {

	private Queue<Token> tkQ;
	private Stack<Token> stack;
	private boolean isInit = false;
	
	public If(final Queue<Token> inTkQueue, final Stack<Token> stack) {
		this.tkQ = inTkQueue;
		this.stack = stack;
		this.isInit = true;
	}

	/**
	 * <Expression> ::= <Multiply> <PlusOpt>;
	 */
	private boolean expression() {
		if(multiply()){
			return plusOpt();
		}
		return false;
	}

	/**
	 * <PlusOpt> ::= "&&" <Multiply> | "||" <Multiply> | null;
	 */
	private boolean plusOpt() {
		return true;
	}

	/**
	 * <Multiply> ::= <Unit> <MultiplyOpt>;
	 */
	private boolean multiply() {
		if (unit()) {
			return multiplyOpt();
		}
		return false;
	}

	/**
	 * <MultiplyOpt> ::= ">" <Unit> | "<" <Unit> | null;
	 */
	private boolean multiplyOpt() {
		Token op = this.tkQ.peek();
		int code = op.getCode().getCode();
		if(code >= WordEnum.EQ.getCode() && code <= WordEnum.LE.getCode()){
			op = this.tkQ.poll();
			Token t1 = this.stack.pop();
			if (unit()) {
				SyntaxTuple st = new SyntaxTuple();
				st.opcode(op);
				st.t1(t1);
				st.t2(this.stack.pop());
				st.t3(TempToken.create(Word.IR_BOOL));
				this.stack.push(TempToken.poll());
				SyntaxTupleList.add(st);
				return true;
			}else{
				return false;
			}
		}
		return true;
	}

	/**
	 * <Unit> ::= identifier | "(" <Expression> ")" | number;
	 * 
	 * @return
	 */
	private boolean unit() {
		Token tk = this.poll();
		//System.out.println(tk);
		if (tk.getCode() == WordEnum.ID) {
			stack.push(tk);
			return true;
		} else if (tk.getCode() == WordEnum.LP) {
			this.expression();
			tk = this.tkQ.poll();
			if (tk.getCode() != WordEnum.RP) {
				ErrorUtils.error("if syntax error");
				return false;
			}
			return true;
		}
		return false;
	}
	private Token poll(){
		if(isInit){
			isInit = false;
			if(!stack.isEmpty()){
				return stack.pop();
			}
		}
		return this.tkQ.poll();
	}

	private boolean block() {
		return expression();
	}

	@Override
	public boolean complier() {
		boolean success = block();
		return success;
	}

	public static void main(String[] args) {
		Queue<Token> tkQ = new LinkedList<>();
		Stack<Token> s = new Stack<>();
//		s.push(new Token(WordEnum.LP, "("));
		s.push(new Token(WordEnum.ID, "a"));
		//tkQ.offer(new Token(WordEnum.ID, "a"));
		tkQ.offer(new Token(WordEnum.GT, ">"));
		tkQ.offer(new Token(WordEnum.ID, "b"));
		//tkQ.offer(new Token(WordEnum.RP, ")"));
		//tkQ.offer(new Token(WordEnum.MUL, "?"));
		//tkQ.offer(new Token(WordEnum.ID, "d"));
		tkQ.offer(Word.TK_EOF);
		If op = new If(tkQ, s);
		op.complier();
		System.out.println(SyntaxTupleList.tupleList);
	}

}
